package com.huffman.smart_picture.aop.aspect;

import cn.hutool.core.collection.CollUtil;
import com.huffman.smart_picture.annotation.CheckAnyAuth;
import com.huffman.smart_picture.annotation.CheckAnyRole;
import com.huffman.smart_picture.auth.SpaceUserAuthManager;
import com.huffman.smart_picture.auth.model.SpaceUserRole;
import com.huffman.smart_picture.auth.request.SpaceUserRequest;
import com.huffman.smart_picture.common.UserSession;
import com.huffman.smart_picture.common.auth.AuthConstant;
import com.huffman.smart_picture.common.exception.BusinessException;
import com.huffman.smart_picture.common.exception.ErrorEnum;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Arrays;
import java.util.List;

/**
 * @author yrforest
 * @version 1.0
 * @description: 空间权限/角色校验切面
 * @date 2025/6/29 13:23
 */
@Component
@Aspect
public class CheckRoleAndAuthAspect {

    @Resource
    SpaceUserAuthManager spaceUserAuthManager;

    @Before("@annotation(com.huffman.smart_picture.annotation.CheckAnyRole)")
    public void checkAnyRole(JoinPoint joinPoint) {
        HttpServletRequest httpServletRequest = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        UserSession userSession = (UserSession) httpServletRequest.getSession().getAttribute(AuthConstant.LOGIN_USER);

        if (userSession == null) {
            throw new BusinessException(ErrorEnum.AUTHENTICATION_FAIL, "请求失败", "未登录");
        }

        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        CheckAnyRole checkAnyRole = method.getAnnotation(CheckAnyRole.class);
        String[] roles = checkAnyRole.roles();
        if (roles.length == 0) {
            return;
        }

        Object[] args = joinPoint.getArgs();
        Long spaceId = null;
        // 两种传参方式 json/query
        if (args[0] instanceof SpaceUserRequest) {
            SpaceUserRequest spaceUserRequest = (SpaceUserRequest) args[0];
            spaceId = spaceUserRequest.getId();
        } else {
            spaceId = (Long) args[0];
        }
        if (spaceId == null) {
            throw new BusinessException(ErrorEnum.PARAM_CHECK_MISTAKE, "空间id为空");
        }
        // 根据空间id 获取用户角色类别
        Integer spaceUserRoleType = userSession.getSpaceUserRoleMap().get(spaceId);
        SpaceUserRole spaceUserRole = spaceUserAuthManager.getSpaceUserRole(spaceUserRoleType);
        String role = spaceUserRole.getRole();
        if (!Arrays.asList(roles).contains(role)) {
            throw new BusinessException(ErrorEnum.NO_AUTH, "用户权限不足");
        }
    }

    @Before("@annotation(com.huffman.smart_picture.annotation.CheckAnyAuth)")
    public void checkAnyAuth(JoinPoint joinPoint) {
        HttpServletRequest httpServletRequest = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        UserSession userSession = (UserSession) httpServletRequest.getSession().getAttribute(AuthConstant.LOGIN_USER);

        if (userSession == null) {
            throw new BusinessException(ErrorEnum.AUTHENTICATION_FAIL, "请求失败", "未登录");
        }

        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        CheckAnyAuth checkAnyAuth = method.getAnnotation(CheckAnyAuth.class);
        String[] auths = checkAnyAuth.auths();
        if (auths.length == 0) {
            return;
        }
        Object[] args = joinPoint.getArgs();
        Long spaceId = null;
        // 两种传参方式 json/query
        if (args[0] instanceof SpaceUserRequest) {
            SpaceUserRequest spaceUserRequest = (SpaceUserRequest) args[0];
            spaceId = spaceUserRequest.getId();
        } else {
            spaceId = (Long) args[0];
        }
        if (spaceId == null) {
            throw new BusinessException(ErrorEnum.PARAM_CHECK_MISTAKE, "空间id为空");
        }
        // 根据空间id 获取用户角色权限
        Integer spaceUserRoleType = userSession.getSpaceUserRoleMap().get(spaceId);
        SpaceUserRole spaceUserRole = spaceUserAuthManager.getSpaceUserRole(spaceUserRoleType);
        List<String> permissions = spaceUserRole.getPermissions();
        if (!CollUtil.containsAny(Arrays.asList(auths), permissions)) {
            throw new BusinessException(ErrorEnum.NO_AUTH, "权限不足");
        }
    }
}
